package com.aipartner.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * JWT Utility Class
 * 
 * @author AI Partner Team
 * @since 2024-01-20
 */
@Component
@Slf4j
public class JwtUtil {
    
    @Value("${jwt.secret:ai-partner-secret-key}")
    private String secret;
    
    @Value("${jwt.expiration:86400}")
    private Long expiration;
    
    /**
     * Generate JWT token
     * 
     * @param userId User ID
     * @param username Username
     * @return JWT token
     */
    public String generateToken(String userId, String username) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            Date expiryDate = new Date(System.currentTimeMillis() + expiration * 1000);
            
            return JWT.create()
                    .withSubject(username)
                    .withClaim("userId", userId)
                    .withIssuedAt(new Date())
                    .withExpiresAt(expiryDate)
                    .sign(algorithm);
        } catch (Exception e) {
            log.error("Error generating JWT token", e);
            return null;
        }
    }
    
    /**
     * Get username from token
     * 
     * @param token JWT token
     * @return Username
     */
    public String getUsernameFromToken(String token) {
        try {
            DecodedJWT jwt = decodeToken(token);
            return jwt.getSubject();
        } catch (Exception e) {
            log.error("Error getting username from token", e);
            return null;
        }
    }
    
    /**
     * Get user ID from token
     * 
     * @param token JWT token
     * @return User ID
     */
    public String getUserIdFromToken(String token) {
        try {
            DecodedJWT jwt = decodeToken(token);
            return jwt.getClaim("userId").asString();
        } catch (Exception e) {
            log.error("Error getting user ID from token", e);
            return null;
        }
    }
    
    /**
     * Validate JWT token
     * 
     * @param token JWT token
     * @return Whether token is valid
     */
    public boolean validateToken(String token) {
        try {
            decodeToken(token);
            return true;
        } catch (Exception e) {
            log.debug("Token validation failed: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * Decode JWT token
     * 
     * @param token JWT token
     * @return Decoded JWT
     */
    private DecodedJWT decodeToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTVerifier verifier = JWT.require(algorithm).build();
        return verifier.verify(token);
    }
}